Jump to page sections
Initial date of publishing: 2022-01-27.

I researched the topic of sorting in PowerShell, ascending and descending, at the same time, having a memory of how it was done, but failing to remember the specifics, and found an acceptable answer on docs.microsoft.com here (example 5), as well as one on Stack Overflow here.

Having read that, I decided to quickly blog a few details that are missing in those answers. I will be using the Sort-Object cmdlet, as they also do. The code is compatible with PowerShell versions 2 to 7 (at the time of writing, presumably also in later versions).

NB! The code style is not how I normally write code, or how you should normally write code. It is so it will be easier to read on a mobile device.

To reproduce, we can create a hashtable of test values.

PS /> $h = @{ba=1; bb=2; bc=3; 
bd=3; bba=4; c=4}

PS /> $h


Name         Value
----         -----
bba          4
bd           3
bc           3
c            4
ba           1
bb           2

For the Sort-Object's -Property parameter, you can specify a hashtable with an "Expression" key and value corresponding to the property to target. What was missing in the other answers is that there are two keys to control the behaviour. Most commonly known is using the key "Descending", but you can also use the key "Ascending", with opposite behaviour, of course.

You specify the hashtable as seen in the below examples.

We will sort descending on Value and ascending on Name.

First Way

PS /> $h.GetEnumerator() | 
Sort-Object -Property @{
Expression = "Value"; Descending = $True},
@{Expression = "Name"; Descending = $False}


Name        Value
----        -----
bba         4
c           4
bc          3
bd          3
bb          2
ba          1

Notice how the values are sorted descendingly and the names are sorted ascendingly. There are four more ways to do the same (that I can think of at the time of writing.)

The second alternative is using "Name" instead of a hashtable with explicit ascending sort, because that's the default.

Second Way

PS /> $h.GetEnumerator() | 
Sort-Object -Property @{
 Expression = "Value"; Descending = $True},
 Name

Name        Value
----        -----
bba         4
c           4
bc          3
bd          3
bb          2
ba          1

The third alternative is inverting the bools (true/false) - and using "Ascending" instead of "Descending".

Third Way

PS /> $h.GetEnumerator() | 
Sort-Object -Property @{
 Expression = "Value"; Ascending = $False}, 
 @{Expression = "Name"; Ascending = $True}  


Name        Value
----        -----
bba         4
c           4
bc          3
bd          3
bb          2
ba          1

Fourth Way

The fourth alternative, is using the -Descending parameter for Sort-Object cmdlet, and using Descending = $False for the "Name" property.

PS /> $h.GetEnumerator() | 
 Sort-Object -Property Value, 
 @{
  Expression = "Name";
  Descending = $False} -Descending


Name        Value
----        -----
bba         4
c           4
bc          3
bd          3
bb          2
ba          1

And fifth and finally, the same as the previous example, only with the "Ascending" key.

Fifth Way

PS /> $h.GetEnumerator() | 
Sort-Object -Property Value,
@{Expression = "Name"; 
Ascending = $True} -Descending  

Name        Value
----        -----
bba         4
c           4
bc          3
bd          3
bb          2
ba          1

That should cover all the cases? If you have anything to add, send me a mail at svendsentech@gmail.com.

Be well. 😙

Powershell      Sorting      Windows      Programming          All Categories

Google custom search of this website only

Minimum cookies is the standard setting. This website uses Google Analytics and Google Ads, and these products may set cookies. By continuing to use this website, you accept this.

If you want to reward my efforts